package com.citrix.gs.util.beacon;

import java.util.Arrays;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.citrix.gs.util.RepositoryDeployer;
import com.offbytwo.jenkins.model.BuildResult;

public class Repository {
    
    private static final Logger logger = LoggerFactory.getLogger(Repository.class);
    
    @Override
    public String toString() {
        return this.getName();
    }

    private String group = null; // product group
    private String product = null;
    private String component = null;
    private String branch = null;
    private String supplementary = null; 
    private Scm scm; // Source control management
    private List<String> tools;
    public Scm getScm() {
        return scm;
    }

    public void setScm(Scm scm) {
        this.scm = scm;
    }
    
    public Repository() {
    }
    
    // Construct a repository from name, e.x. XenMobile-MDXiOS-Gauntlet1
    public Repository(String name) throws Exception { 
       String [] s =name.split("-");
       if(s.length != 3) {
           throw new Exception("The repository name is not valid, please check");
       }
       
       product = s[0];
       component = s[1];
       branch = s[2];
    }
    
    public Repository(String g, String p, String c, String b) {
        this.group = g;
        this.product = p;
        this.component = c;
        this.branch = b;
    }
    
    public Repository(String g, String p, String c, String b, Scm scm) {
        this(g, p, c, b);
        this.scm = scm;
    }
    
    public Repository(String g, String p, String c, String b, Scm scm, List<String> t) {
        this(g, p, c, b, scm);
        this.tools = t;
    }
    
    public Repository(String g, String p, String c, String b, String s, Scm scm, List<String> t) {
        this(g, p, c, b, scm);
        setSupplementary(s);
        this.tools = t;
    }
    
    public String getGroup() {
        return group;
    }
    public void setGroup(String group) {
        this.group = group;
    }
    public String getProduct() {
        return product;
    }
    public void setProduct(String product) {
        this.product = product;
    }
    public String getComponent() {
        return component;
    }
    public void setComponent(String component) {
        this.component = component;
    }
    public String getBranch() {
        return branch;
    }
    public void setBranch(String branch) {
        this.branch = branch;
    }
    public List<String> getTools() {
        return tools;
    }
    public void setTools(List<String> tools) {
        this.tools = tools;
    }
    
    public String getPath(boolean closed) {
        
        if(closed) {
            return Arrays.asList(group, product, component, branch).stream().reduce((s1, s2) ->( s1+ "/" + s2)).get();
        } 
        return getPath();
    }
    
    public String getPath() {
        return group + "/" + product + "/" + component + "/" + branch + "/";
    }
    
    public String getLabel() {
        return group + "_" + product + "_" + component + "_" + branch;
    }
    
    public String getName() {
        return product + "-" + component + "-" + branch + (supplementary == null || supplementary.isEmpty()? "" : "-" + supplementary);
    }


	public String getSupplementary() {
		return supplementary;
	}

	public void setSupplementary(String supplementary) {
		this.supplementary = supplementary;
	} 
	
	
	public boolean testDeploy(RepositoryDeployer deployer) {
	    
	    return deployer.doTestDeploy(false, this);  
	}
	
	public boolean testDeploy(RepositoryDeployer deployer, boolean force) {
        
        return deployer.doTestDeploy(force, this);  
    }
	
	public boolean prodDeploy(RepositoryDeployer deployer, boolean force) {
        
        return deployer.doProdDeploy(this, force);  
    }
	
	public boolean checkStatus(BeaconCI ci) {
	    
        return ci.getJobNames(this.getName())
                .stream()
                .map(jobName -> {
                    try {
                        BuildResult buildResult = ci.getJob(jobName).getLastBuild().details().getResult();
                        
                        if(buildResult != BuildResult.SUCCESS) {
                            logger.error("Last build result of job: {} on test ic: {} is {}", jobName, ci.getHostURL(), buildResult);
                        } else {
                            return true;
                        }
                        
                    } catch (Exception e) {
                        logger.error("Fail to check last build result of job: {}", jobName, e);
                    }
                    
                    return false;
                })
                .reduce((r1,r2) -> r1 && r2)
                .get();
    }
}
